package com.multdb.aop.config.dbconfig;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class DynamicDataSourceAspect {

	@Around("@annotation(targetDataSourceAnno)")
	public Object aroundOperDeal(ProceedingJoinPoint pjp, TargetDataSourceAnno targetDataSourceAnno) throws Throwable {
		DBContextHolder.setDBType(targetDataSourceAnno.value());
		Object retVal = pjp.proceed();
		DBContextHolder.clearDBType();
		return retVal;
	}

	@Pointcut("!@annotation(com.multdb.aop.config.dbconfig.TargetDataSourceAnno) " +
			"&& (execution(* com.multdb.aop.service..*.select*(..)) " +
			"|| execution(* com.multdb.aop.service..*.get*(..)))")
	public void readPointcut() {

	}

	@Pointcut("@annotation(com.multdb.aop.config.dbconfig.TargetDataSourceAnno) " +
			"|| execution(* com.multdb.aop.service..*.insert*(..)) " +
			"|| execution(* com.multdb.aop.service..*.add*(..)) " +
			"|| execution(* com.multdb.aop.service..*.update*(..)) " +
			"|| execution(* com.multdb.aop.service..*.edit*(..)) " +
			"|| execution(* com.multdb.aop.service..*.delete*(..)) " +
			"|| execution(* com.multdb.aop.service..*.remove*(..))")
	public void writePointcut() {

	}

	@Before("readPointcut()")
	public void read() {
		DBContextHolder.slave();
	}

	@Before("writePointcut()")
	public void write() {
		DBContextHolder.master();
	}


	/**
	 * 另一种写法：if...else...  判断哪些需要读从数据库，其余的走主数据库
	 */
//    @Before("execution(* com.multdb.aop.service.impl.*.*(..))")
//    public void before(JoinPoint jp) {
//        String methodName = jp.getSignature().getName();
//
//        if (StringUtils.startsWithAny(methodName, "get", "select", "find")) {
//            DBContextHolder.slave();
//        }else {
//            DBContextHolder.master();
//        }
//    }
}